﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DomainModel.Entities;
using NHibernate;
using NHibernate.Criterion;
using DomainModel.Abstract;

namespace DomainModel.Concrete
{
    public class UsersRepository : IUsersRepository
    {
        public IEnumerable<User> GetAll()
        {
            ICriteria criteria = SessionManager.CurrentSession.CreateCriteria(typeof(User)).AddOrder(Order.Desc("UserID"));
            return criteria.List<User>();
        }

        public User GetByOpenID(string openID)
        {
            ICriteria criteria = SessionManager.CurrentSession.CreateCriteria(typeof(User));
            return criteria.Add(Expression.Eq("OpenID", openID)).List<User>().FirstOrDefault();
        }

        public User Get(int? id)
        {
            return SessionManager.CurrentSession.Get<User>(id);
        }

        public void Save(User user)
        {
            ISession session = SessionManager.CurrentSession;
            session.BeginTransaction();
            session.SaveOrUpdate(user);
            session.Transaction.Commit();
        }

        public void Merge(User user)
        {
            ISession session = SessionManager.CurrentSession;
            session.BeginTransaction();
            session.Merge(user);
            session.Transaction.Commit();
        }

        public void Delete(int id)
        {
            SessionManager.CurrentSession.Delete(Get(id));
        }
    }
}


/*
The usage and semantics of saveOrUpdate() seems to be confusing for new users. Firstly, so long as you are not trying to use instances from one session in another new session, you should not need to use update(), saveOrUpdate(), or merge(). Some whole applications will never use either of these methods.

Usually update() or saveOrUpdate() are used in the following scenario:

the application loads an object in the first session
the object is passed up to the UI tier
some modifications are made to the object
the object is passed back down to the business logic tier
the application persists these modifications by calling update() in a second session
saveOrUpdate() does the following:

if the object is already persistent in this session, do nothing
if another object associated with the session has the same identifier, throw an exception
if the object has no identifier property, save() it
if the object's identifier has the value assigned to a newly instantiated object, save() it
if the object is versioned by a <version> or <timestamp>, and the version property value is the same value assigned to a newly instantiated object, save() it
otherwise update() the object
and merge() is very different:

if there is a persistent instance with the same identifier currently associated with the session, copy the state of the given object onto the persistent instance
if there is no persistent instance currently associated with the session, try to load it from the database, or create a new persistent instance
the persistent instance is returned
the given instance does not become associated with the session, it remains detached
*/